<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Type-less with Tyle</title>

<style type="text/css">
BODY {
	background-color: #e8f8ff;
}
TABLE {
	width: 100%;
	border-width: 2;
	border-color: #000000;
	background-color: #000000;
	border-spacing: 0.2;
	padding: 0;
}	
TD { 
	background-color: #d0f0f0;
	padding: 3;
}	
TD.b {
	background-color: #c0e0e0;
}
code {
	background-color: #ffffff;
}
p { margin-top: 10px; margin-bottom: 10px; line-height: 16px;}
</style>
</head>
<body>
	<table>
	 <tr>
    <td align=middle><img src="tyle.gif" width=265 height=97 alt="Tyle">
	  <h1 style="margin:0;">
      <div style="position:absolute;left:20px;color:#444488;">Language specification</div>
      Type less with Tyle
    </h1>
	</table>
	<h1>Tyle introduction</h1>
<p>Tyle is a general programming language that is especially fit for automation, web services, and operations on textual or binary files that contain proprietary data formats. Functionally is it similar to Perl, but conceptually closer to Javascript.</p>
<p>Tyle is currently used in a Wiki implementation, in a logging tool for project management, some small games, and various automation tasks like simulating series of keyboard- and mouse clicks to control window applications.</p>
<p>Its syntax departs from C. However, a piece of Tyle code might not resemble a piece of C code much, because a) Tyle contains some powerful operators that are not C/C++, b) because it lacks static typing (only static type hinting), c) because it lacks keywords, d) argument stacking is decoupled from function calling: There is a global variable stack, which is manipulated by a couple of operators., e) functions are first-class.</p>
<p>Powerful operators include: list iterator, matrix column iterator, parser operator (parses Tyle code on the fly), operators for generating functions on the fly (handy for higher-order functions).</p>
<p>All of this makes Tyle code so dense that most functions you will find or create will fit on one line of text.</p>
<p>This interpreter consists of an executable that executes Tyle scripts, and a .dll library that enables Tyle scripts to run and interact with an application.</p>
<p>At this moment the application only builds on windows (using mingw) because of some specific windows bindings (for windows automation functions).</p>
<p>A future version will decouple bindings into seperate loadable dll's. This way the core part can be built for Linux as well.</p>
  <h1>Grammar</h1>
  To simplify the description, the operator precedence is described seperately in the next chapter.
  <pre>
  Program      := Chain
  Chain        := Expression | Expression Seperator Chain | <empty>
  SeqChain     := Expression | Expression ';' | Expression ';' Chain
  Expression   := TypeAssign Item | Item | Operation
  Item         := List | Sequence | Constant | Variable
  Seperator    := ';' | ','
  Constant     := String | Integer | Float | ExprObject | NullObject | Reference | RegExp
  Variable     := Identifier | '.' Identifier | StackVar
  StackVar     := '$' | '$2' | '$3' | ... | '$a' | ....
  List         := '{' Chain '}' | '(' Chain ',' Chain ')'
  Sequence     := '(' SeqChain ')' 
  Map          := '{:' MapChain '}' 
  MapChain     := MapElement | MapElement ',' MapChain
  MapElement   := Expression | Expression '=>' Expression
  String       := '"' C_Text '"' | ''' Literal_Text '''
  RegExp       := '`' Literal_Text '`' RegExpOptions
  RegExpOptions:= 'i' | 'm' | 'o' | RegExpOptions RegExpOptions
  Reference    := '&' Constant
  Params       := Identifier | Identifier ',' Params | <empty>
  ParamSets    := '<' Params '>' ParamSets | <empty>
  ExprObject   := '?' ParamSets Expression
  NullObject   := '()'
  Operation    := Expression PostfixOp | PrefixOp Expression | Expression BinaryOp Expression | Switch | Index | Call
  PrefixOp     := '*' | '*!' | '&' | '!' | '+' | '-' | '@' | '@@' | '?' | '.?'
  PostfixOp    := '!' | '.*' | '.@' | '[]'
  BinaryOp     := '.' | '*' | '/' | '%' | '@' | '+' | '-' | '<<' | '>>' | '+<' |
                  ':+' | ':-' | '<' | '<=' | '>=' | '>' | '==' | '!=' | 
                  ':@' | '.!' | ':!' | '%!' | '.?'
                  '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | ':+=' | ':-='
  Switch       := Expression '?' Cases
  Cases        := ':' | Expression | Expression ':' Cases
  Index        := Expression '[' Expression ']' | Expression '.' StructItem | Expression '.@' StructItem
  Call         := Expression List | Expression Sequence
  TypeAssign   := '[' Type ']' | '[' '=' Type ']'
  Type         := Struct | ':' Type | Type '=>' Type
  Struct       := '{' StructItems '}' | StructVar ['=' Struct]
  StructItems  := StructItem | StructItem ',' StructItems | '...'
  StructVar    := Identifier
  StructItem   := Identifier | TypeAssign Identifier
  </pre>
  <h1>Basic types</h1>
  <ol>
		<li>Null</li>
		<li>List</li>
		<li>Integer</li>
		<li>Float</li>
		<li>String</li>
		<li>ExprObject</li>
		<li>Reference</li>
		<li>Map</li>
		<li>RegExp</li>
  </ol>		
  <p>Of any object, the <code>@@</code> prefix-operator will return the basic type number.</p>
  <h1>Literals</h1>
  <ul>
  <li>List: <code>{...}</code> or <code>(..., ...)</code>.  Series of expressions that construct a list object. Putting a <code>;</code> after an item in the list instead of a <code>,</code> will prevent the result of that expression to be part of list. A list can be a mix of different types.
  <li>Sequence: <code>(...; ...)</code>. Series of expressions to be evaluated, but only the result of the last expression will be the final result. If the chain however ends in a ';', the Sequence results in a Null object.
  <li>Map: <code>{: a=>b, c, d=>e,...}</code>. Series of expression pairs or single expressions. A mapping is constructed by a pair <code>a => b</code>, but just single element will result in a mapping of a key with a null object. A set ( an unordered collection of unique elements) is basically a map of single elements.
  <li>Variable: A variable is either a:
    <ul>
    <li>Global variable, defined and referred by, for example <code>fooBar</code>.
    <li>Local variable, defined by, for example <code>.fooBar</code>, and referred likewise or without the <code>.</code>.
    <li>Stack variable, can either be referred by <code>$, $2, ...</code>, where the number indicates the depth; or be referred by <code>$a, $b, ...</code>, where the letter indicates the depth from the expression execution (where $a will normally refer to the arguments of an function expression). Stack variables are created by operations <code>a.!b</code>, <code>a:!b</code>, <code>a%!b</code>, and <code>b(a)</code>. In those cases the value of <code>$</code> will be of expression <code>a</code> and available within expression <code>b</code> only. Within <code>b</code>, <code>$2</code> will refer to the stack variable of the context of the higher level expression, and this proces enumerates for <code>$3</code>, etc.
    </ul>
  <li>Parameters: <code>&lt;single_param&gt;</code> or <code>&lt;param1, param2, ...&gt;</code>. Binds stack elements to identifiers. <code>?&lt;x,y&gt;(x+y)</code> is equivalent to <code>?( [{x,y}]$; $.x+$.y )</code>
  <li>String: series of bytes, byte 0 can be included using <code>\0</code>. single-quotes(') create literal strings, which is handy for paths (example: 'c:\temp\t.txt'), while double-quotes(") create c-style strings in which <code>\t</code>, <code>\n</code>, <code>\r</code>, <code>\xNN</code>, <code>\0</code> have special meaning (example: "hello world!\n").
  <li>RegExp: Regular expression string, enclosed by `...` and a subset of the letters 'i', 'm', 'o' appended, indicating the RegExp options. 'i' for 'case-insensitivity', 'm' for 'multi-line', and 'o' for 'once'.<br>
Regular Expression components are: <br>
escape: <code>\x</code>: where x is <code>\</code>, <code>`</code>, <code>n</code>, <code>r</code>, <code>t</code><br>
any: <code>.</code> <br>
start: <code>^</code> <br>
end: <code>$</code> <br>
range: <code>[a-z]</code> <br>
not in range: <code>[^a-z]</code> <br>
zero or more: non-greedy: <code>e*</code>, or greedy: <code>e**</code> <br>
optional: non-greedy: <code>e?</code>, or greedy: <code>e??</code> <br>
one or more: non-greedy: <code>e+</code>, or greedy: <code>e++</code> <br>
min-max: non-greedy: <code>e{*1-5}</code>, or greedy: <code>e{**1-5}</code> <br>
tagged expression: <code>(e)</code> <br>
sub-expression: <code>{e}</code> <br>
look ahead: <code>{?e}</code> <br>
look before: <code>{?e}</code>, which must be at the beginning of the regular expression.<br>
or: <code>e|f</code> (this has the lowest priority)
  <li>Reference: fulfills the role of both C references and C pointers. Most of the time you don't need to derefence pointers because most operators do that automatically, except <code>*</code>, <code>*!</code>, <code>&</code>,<code>=</code>,<code>==</code>,<code>@</code>(binary), <code>!=</code>, and function <code>hash</code>. <code>&x</code> will generate a reference object to object x, and <code>*y</code> will dereference manually. <code>*!y</code> will dereference until a non-reference object.
  </ul>
  <h1>Typing</h1>
	A Type can be attached to a variable. This acts as a hint, meaning the actual value of the variable does not have to adhere to the Type.
  A Type is either a) a 'Struct' in which every element has an identifier and optionally coupled with a sub-'Type', b) it is a list in which every element has the same Type (using prefix <code>:</code>), or c) it is a map in which every key and/or data has a certain Type (using <code>a=>b</code>), <code>=>b</code>, or <code>a=></code>).<br> 
  Types are defined within <code>[]</code> brackets, before the variable. Such a variable can be always assigned a different Struct, but the Type of a '$'-variables is only overwritten when there is a '=' behind the '['. Besides assigning a Type to a Type identifier, it is also possible to concatenate Structs using the + operator.<br>
  To get an element of a Struct, use <code>a.b</code>. Other operators are explained in chapter 'Operators'.
  Examples:<br>
    <p><code>[{x,y}] pos={(),()};</code><br>
    <code>[color={r,g,b}]; [crd={x,y,[color] c}] pos={{},{}}; pos.c.g=3;</code> &rarr; <code>pos[2][1]=3;</code><br>
    <code>[color=color+{alpha}]; pos.c.@alpha;</code> &rarr; <code>3</code><br>
    <code>[coords=:{x,y}]; [coords]l={{100,100},{150,120},{120,150}};l[1].y</code> &rarr; <code>120</code><br>
    <code>[screen= {x,y}=>{r,g,b}]; [screen]l={:}; (l:+={10,20})={1,2,0}; l[{10,20}].g</code>&rarr; <code>2</code><br>
    <code>[coordSet= {x,y}=>]; [coordSet]l={:{1,2},{2,0},{0,3} }; {:{2,0},{1,3}}@l </code>&rarr; <code>{:{2,0}}</code></p>
  Enumerations can be formed using <code>var.@elem</code>. Examples:
    <p><code>pos.@y;</code> &rarr; <code>1;</code><br></p>
	<h1>Starting Tyler (Tyle shell)</h1>
	Start Tyler.bat. This will call Tyler.exe and loads the standard libraries.
	Starting Tyler.exe directly will not load these libraries. <code>#q&lt;enter&gt;</code> will quit Tyler. 
	<h1>Learning Tyle by using Tyler</h1>
	<p>Call the function <code>globals</code> by typing <code>globals!&lt;enter&gt;</code> or <code>globals()&lt;enter&gt;</code> (C/C++ notation).
	Now the complete list of all built-in functions, library functions and global variables will be listed.</p>
	<p>For every library function, just typing it and pressing &lt;enter&gt; will give the definition of that function. However, using the <code>indent</code>-function makes it is more readible, like: <code>indent(caps)</code>. Another help-function is <code>expr2html</code>, which will clearify precedence within a function using html. With these functions both the language and the meaning of that function can be learned.</p>
	<p>Type <code>help!</code> to get this language reference help file.</p>
 <h1>Operators</h1>
  <h2>Meaning</h2>
  Operands are expressions that evaluate to the following type or are converted automatically to the following type:<br><b>n</b>: null, <b>l</b>: list, <b>i</b>: integer, <b>f</b>: float, <b>s</b>: string, <b>e</b>: exprObject, <b>r</b>: Reference, <b>m</b>: Map, <b>re</b>: RexExp, <b>*</b>: any object type, <b>a</b>: same as operand 'a', <b>x</b>: according certain rule.<br>'<b>se</b>' indicates Struct element identifier instead of an expression operand.<br><br>
  <table>
    <tr><td class="b">Operation<td class="b">a type<td class="b">b type<td class="b">Result<td class="b">Description
  	<tr><td><code>a+b</code>       <td>i, f<td>i, f<td>a<td>addition. 
    <tr><td>                       <td>l, s<td>l, s<td>a<td>append (strings and lists)<br>examples: <code>"foo" + "bar"</code>
  	<tr><td>                       <td>l<td>m<td>a<td>Appends a map by converting it first to a list of list of {key,data}.
    <tr><td>                       <td>m<td>m<td>a<td>Return <code>a</code> with the mappings of <code>b</code> added, but never overwritten.
    <tr><td>                       <td>re<td>re<td>re<td>Appends b to a, using RegExp options of a</code>
    <tr><td>                       <td>re<td>*<td>re<td>Converts b to a string, which is appended to a, without interpreting the string as a RegExpr</code>
    <tr><td><code>a-b</code>       <td>i, f<td>i, f<td>a<td>substract. 
    <tr><td>                       <td>l, s<td>l, s<td>a<td>removes all occurrences of <code>b</code> from <code>a</code>.
    <tr><td>                       <td>m<td>m<td>a<td>removes all mappings from <code>a</code> that have keys in <code>b</code>.
    <tr><td><code>a/b</code>       <td>i, f<td>i, f<td>a<td>divide. 
    <tr><td>                       <td>l<td>i<td>a<td><code>a</code> cut into <code>b</code> number of sublists.  
    <tr><td><code>a%b</code>       <td>i, f<td>i<td>a<td>modulo.
    <tr><td>                       <td>l<td>i<td>a<td><code>a</code> distributed into <code>b</code> number of sublists.
    <tr><td><code>a*b</code>       <td>i, f<td>i, f<td>a<td>multiply.   
    <tr><td>                       <td>l, s<td>i<td>a<td><code>a</code> concatenated <code>b</code> times.
    <tr><td><code>a|b</code>       <td>i<td>i<td>a<td>Bitwise 'or'.
    <tr><td>                       <td>l<td>l<td>a<td><code>a</code> plus the elements of <code>b</code> that are not already in the result.
    <tr><td><code>a&b</code>       <td>i<td>i<td>a<td>Bitwise 'and'.
    <tr><td>                       <td>l<td>l<td>a<td>Collection of elements both in <code>a</code> and <code>b</code>.
    <tr><td><code>a||b</code>      <td>*<td>*<td>*<td>Logical 'or'. <code>b</code> is only evaluated when <code>a</code> is zero when converted to integer. Result is <code>a ? a : b</code>.
    <tr><td><code>a&&b</code>      <td>*<td>*<td>*<td>Logical 'and'. <code>b</code> is only evaluated when <code>a</code> is not zero when converted to integer. Result is <code>a ? b : a</code>.
    <tr><td><code>a^b</code>       <td>i<td>i<td>a<td>Exclusive or.
    <tr><td>                       <td>l<td>l<td>a<td>Collection of elements only in <code>a</code> or <code>b</code>.
  	<tr><td><code>a>>b,<br>a&lt;&lt;b</code>    <td>i<td>i<td>a<td>shift right/left. If negative numbers are used, <code>b</code> is the amount of elements that remain.
    <tr><td>                       <td>l, s<td>i<td>a<td>removing elements right or left. Shifting with negative number -x on these types will result in shifting until x elements are left.
    <tr><td>                       <td>m<td>*<td>a<td>removing elements left or right that are smaller/larger than b.
  	<tr><td><code>a+&lt;b</code>    <td>l, s<td>l, s<td>a<td>prepend (strings and lists). <i>deprecated: '+>' (use '+' to append)</i><br>examples: <code>"bar" +&lt; "foo"</code>
  	<tr><td>                       <td>l<td>m<td>a<td>prepends a map by converting it first to a list of list of {key,data}.
    <tr><td><code>a[b]</code>     <td>l, s<td>i<td>x<td>gets element <code>b</code> from <code>a</code>.<br>In case of a string it returns the character in a writable string.<br>If a negative number is used the index is relative to the end of the list. Example: </code>str="hi?";str[2]="!";str</code> &rarr; <code>"hi!"</code>.<br>In case of assigning a value or pointing to an index outside list length, list is expanded with <code>()</code>'s. Example: <code>x={}; x[3]=1;</code> &rarr; <code>{(),(),(),1}</code>.
    <tr><td>                      <td>m<td>*<td>x<td>gets data belonging to key <code>b</code> from <code>a</code>.
  	<tr><td><code>a[:b]</code>    <td>m<td>i<td>x<td>Gets the b'th key from map A.
  	<tr><td>                      <td>l<td>*<td>i<td>Gets the first index of element b.
  	<tr><td>                      <td>s<td>s<td>i<td>Gets the first index of substring b.
    <tr><td><code>a[]</code>     <td>l<td><td>s<td>returns the name of the Type attached to variable 'a'. Example: </code>[coord]x; x[]</code> &rarr; <code>"coord"</code>
    <tr><td><code>a.*</code>     <td>l<td><td>l<td>returns the names of the elements of the Struct attached to variable 'a'. Example: </code>[{x,y}]v; v.*</code> &rarr; <code>{"x","y"}</code>
    <tr><td><code>a.b</code>     <td>l<td>se<td>l<td>returns the element of List 'a' that corresponds with its Struct element 'b'.
    <tr><td><code>a.@</code>     <td>l<td><td>i<td>returns the amount of elements of the Struct attached to variable 'a'. Example: </code>[{x,y}]v; v.@</code> &rarr; <code>2</code>
    <tr><td><code>a.@b</code>     <td>l<td>se<td>i<td>returns the index of 'b' in the Struct of variable 'a'.
    <tr><td><code>a->b(c)</code>     <td>l<td>se<td>l<td>Short for <code>a.!$[0].b(c)</code>. This function is useful for function calling in object oriented programming. If you want to pass more than one argument use: <code>a{b,c}</code>.
    <tr><td><code>&x</code>        <td>*<td><td>r<td>gets reference to <code>x</code>.
    <tr><td><code>*x</code>        <td>r<td><td>x<td>dereferences <code>x</code>.
    <tr><td><code>*!x</code>        <td>r<td><td>x<td>gets value: Dereferences <code>x</code> until non-reference object is reached.
  	<tr><td><code>@@x</code>       <td>*<td><td>i<td>return type identifier of x: Null=0, List=1, Int=2, Float=3, String=4, Expression=5, Reference=6, Map=7
  	<tr><td><code>a?b:c:d</code>   <td>i<td>*<td>x<td>switch, where <code>b</code> is result when <code>a</code> is not in other case, <code>c</code> is case when <code>a</code> is 0, <code>d</code> is case when <code>a</code> is 1... Only the selected case is evaluated.
  	<tr><td><code>a:@b</code>  <td>l, s<td>i<td>l<td>find indexes where <code>b</code> is not 0.<br><code>{1,2,4,5,6} :@ ($%2==0)</code> &rarr; <code>{1,2,4}</code>
  	<tr><td><code>a.!b</code>   <td>*<td>*<td>x<td><code>a</code> is stacked in the context of <code>b</code>, where <code>$</code> is x, <code>$2</code> is the old <code>$</code>, <code>$3</code> is the old <code>$2</code>, ... 
  	<br>                   examples: <code>1 .! ( $ + $ )</code>        &rarr; <code>2</code>
  	<br>                             <code>1 .! 2 .! ($ + $2)</code>    &rarr; <code>3</code>
  	<tr><td><code>a:!b</code>  <td>l, s<td>*<td>l<td>Iterate over <code>a</code> and collect all non-()-object results in a list. To make the elements changeable, use: <code>&xs:!($=...;)</code>
  	<br>                   examples:  <code>{1,2,3,4} :! ($!=3 ? $*2)</code> &rarr; <code>{2,4,8}</code>
  	<br>                              <code>x="h3llo"; &x :! ($=='3' ? ($='e';);); x</code> &rarr; <code>"hello"</code>
  	<tr><td>                   <td>m<td>i<td>l<td>Iterates on the keys of a map.
  	<br>                   example:  <code>{: "world", "hello " } :! puts!;</code> &rarr; <code>hello world</code>
  	<tr><td><code>a%!b</code> <td>l, s<td>*<td>l<td>column-iterate (on a matrix(list of lists) ) and collect all non-()-object results in a list.
  	<br>                   example: <code>{{1,2},{3,4}} %! $</code>    &rarr; <code>{{1,3},{2,4}}</code>
  	<tr><td>                   <td>m<td>i<td>l<td>Iterates on a structured list of type [{key,data}] in $.
  	<br>                   example:  <code>{: 1=>"hello ", 2=>"world" } %! puts($.data);</code>
  	<tr><td><code>a?!b</code>      <td>i<td>*<td>l<td>while expression: while <code>a</code> is not <code>0</code>, do <code>b</code>, and and collect all non-()-object results in a list.
  	<tr><td><code>a:+b</code>     <td>l,m<td>*<td>a<td>insert <code>()</code> at index or key <code>b</code>. <code>(xs:+=i)=value</code> will insert <code>value</code> in location i. This does not hold for existing keys in maps.
  	<br>                   examples: <code>{"a","b","d"} :+ 2, ({1,3}:+=1)=2, ({:1=>2}:+=4)=5;</code>
  	<tr><td><code>a:-b</code>     <td>l,m<td>*<td>a<td>remove at index or key <code>b</code>.
  	<tr><td><code>?a</code>     <td>*<td><td>e<td>make exprObject
  	<br>                   example: <code>sum = ? ( 0 .! ( $2 :! ($2 += $ ; ) ; $ ) );</code>
  	<tr><td><code>a.?b</code>     <td>*<td><td>e<td>make exprObject <code>? ( a.! b)</code>, which is used for explicit closure.
  	<br>                   example: <code>'Hello world!' .? putline!</code>   &rarr; <code>? ('Hello world!' .! putline!) </code>
  	<tr><td><code>.?a</code>    <td>*<td><td>e<td><code>a</code> as exprObject
  	<tr><td><code>a!</code>     <td>e<td><td>x<td>Evaluates <code>a</code>, but does not put anything on the stack.
  	<br>                   example: <code>{1,2,3} .! sum!</code>   &rarr; <code>6</code>  
  	<tr><td><code>a(b)</code>     <td>e<td>*<td>x<td>Equivalent to <code>b.!(a!)</code>. If you want to pass more than one argument use: <code>a{b,c}</code>.
  	<tr><td><code>a(b)</code>     <td>*<td>*<td>x<td>Converts <code>b</code> to type of <code>a</code>. For regular expressions, <code>a</code> determines the RegExp options.
  	<tr><td><code>-a</code>        <td>i, f<td><td>a<td>Negate. 
    <tr><td>                       <td>l, s<td><td>a<td>mirror: <code>-{1,2,3}</code> &rarr; <code>{3,2,1}</code>
  	<tr><td><code>~a</code>        <td>i<td><td>a<td>Bitwise Negate. 
    <tr><td>                       <td>l<td><td>a<td>Concatenate: <code>~{{1,2},{3,4}}</code> &rarr; <code>{1,2,3,4}</code>
    <tr><td>                       <td>e<td><td>a<td>Same as {}a, but with annotation-in-comments for showing the variable types: g(lobal), l(ocal), c(losure), p(aram).
  	<tr><td><code>!a</code>        <td>i<td><td>i<td>Not operation.
  	<tr><td><code>@a</code>       <td>l, s<td><td>i<td>Length of <code>a</code>.
  	<tr><td><code>a@b</code>      <td>l, s<td>l, s<td>l<td>finds and returns indexes of subset a in b.
  	<tr><td><code>a@b</code>      <td>m<td>m<td>m<td>returns all mappings in b which keys are keys in a as well.
  	<tr><td><code>a@b</code>      <td>re<td>s<td>l<td>returns all matches of RegExp a in b. A 'match' is a list of {position,length,list of register strings}. See also 'RE_match'. 
  	<tr><td><code>a==b</code>      <td>*<td>*<td>i<td>Returns <code>1</code> if, and only if <code>a</code> and <code>b</code> are of the same type, and have the same value, else it returns <code>0</code>.
  	<tr><td><code>a!=b</code>      <td>*<td>*<td>i<td>Equal to <code>!(a==b)</code>.
  	<tr><td><code>a=b</code>      <td>*<td>*<td>b<td>Assigns value of <code>b</code> to <code>a</code>. Returns <code>b</code>.
  	<tr><td><code>a:-=b</code>      <td>l<td>i<td>x<td>Equal to <code>a=a:-b</code>, but returns the removed element.
  	<tr><td><code>a<<=b</code>      <td>l,s<td>i<td>x<td>Equal to <code>a=a << b</code>, but returns the removed elements.
  	<tr><td><code>a>>=b</code>      <td>l,s<td>i<td>x<td>Equal to <code>a=a>>b</code>, but returns the removed elements.
  	<tr><td><code>a-=b</code>      <td>i,f<td>i,f<td>x<td>Equal to <code>a=a-b</code>, but returns zero is below zero, else one.
  	<tr><td><code>a-=b</code>      <td>l,s<td>l,s<td>x<td>Equal to <code>a=a-b</code>, but returns zero is substring not found, else one.
  	<tr><td><code>a+=b<br>a*=b<br></code>...<td>*<td>*<td>n<td>Equal to <code>a=a operator b</code>, but always returns <code>()</code>.
  </table>
  <h2>Precedence</h2>
  <tt>
   . (binary) -><br> 
   () [] (binary) [:] !(postfix)<br>
   * & ! + - @ @@ (unary)<br>
   * / % @ (binary)<br>
   + - +&lt;<br>
   << >> :+ :-<br>
   < <= >= ><br>
   == !=<br>
   &<br>
   ^<br>
   |<br>
   &&<br>
   ||<br>
   ?: (N-ary) ?!<br>
   :@ .! :! %! .?<br>
   ? .? (unary)<br>
   = += -= *= /= %= <<= >>= +&lt;= :+= :-=<br>
  </tt>
  <h2>right-associativity</h2>
  Right associativity for an operator means: x <i>op</i> y <i>op</i> z == x <i>op</i> ( y <i>op</i> z)<br>
  This is true for the following binary operators: <code>= <i>op</i>= ?! ? .! :! :@ %! .?</code>
	<h1>built-in functions</h1>
  <table>
		<tr><td><code>load{filename,start,length}</code><td>Loads (text or binary) file, start en length are optional. 
		Start can be a negative number, in which case it is relative to the end of the file.<br>
		load("functions.tyle")!! &rarr; load text file, convert to function (first '!') and execute (second '!').<br>
		load{"img.bin",0,10} &rarr; loads first 10 bytes.
		<tr><td><code>eval(string)</code><td>Parses tyle code (to exprObject). <br>example: <code>eval("1+1")</code> &rarr; <code>?(1+1)</code>
		<tr><td><code>data.!save{filename,start}</code><td> start parameter (optional) acts like in load.<br>Example: "my first textfile" .! save("file.txt");
		<tr><td><code>info(file) &rarr; list</code><td>Returns file characteristics: {{..modification timestamp..},length,type bits}. Type bits consists of file types: 0x2000=Character, 0x3000=Block, 0x4000=Directory, 0x8000=Regular; and access bits: 0x0040=Executable, 0x0080=Writable, 0x0100=Readable.
		<tr><td><code>getDateTime() &rarr; list</code><td>Returns {yr,mon,day,hr,min,sec}
		<tr><td><code>getTickCount() &rarr; int</code><td>Returns milliseconds since start of computer.
		<tr><td><code>gets() &rarr; str</code><td>Gets line from console
		<tr><td><code>puts(string)</code><td>Prints string on console
		<tr><td><code>sys{command,input} &rarr; list</code><td>Executes system command. The input string is optional. The result is: {return value,output string}. Mostly used in conjuction with cmd. Example: <code>sys(cmd('del tempfile.dat'))</code>
		<tr><td><code>sleep(millisecs)</code><td>Delay execution
		<tr><td><code>hash(object)</code><td>Generates an hash value of an object. Reference objects are not derefenced, but the hash represents the memory position. 
		<tr><td><code>getcb() &rarr; str</code><td>Get Clipboard text
		<tr><td><code>setcb(str)</code><td>Set Clipboard text
		<tr><td><code>toAscii(str) &rarr; int</code><td>Get ASCII value from one char string
		<tr><td><code>fromAscii(v) &rarr; str</code><td>Make one char string from ASCII value
		<tr><td><code>winGetFirst(h) &rarr; int</code><td>Get first child of window H or if H is zero, get first window 
		<tr><td><code>winGetNext(h) &rarr; int</code><td>Get next Window
		<tr><td><code>winGetParent(h) &rarr; int</code><td>Get parent Window
		<tr><td><code>winSendKey{v,c}</code><td>Send virtual key <code>v</code> with configuration bits <code>c</code>. Use winKeys instead of this one.
		<tr><td><code>winSendMouseEvent{evts,x,y,c}</code><td>Send event bits <code>evts</code> at position (x,y) with optional configuration <code>c</code>. Use winClick or winMouse instead of this function directly.
		<tr><td><code>winGetMousePos(isabs)</code><td>Gets mouse position, if isAbs is not zero, the absolute position is returned.
		<tr><td><code>winGetIdleTime()</code><td>Returns number of millisecs since last keyboard or mouse activity.
		<tr><td><code>winGetKeyState(vkey)</code><td>Returns state of key 'vkey'.
		<tr><td><code>winActivate(h)</code><td>Bring to front and activate
		<tr><td><code>winGetActive() &rarr; int</code><td>Get current active window
		<tr><td><code>winGetName(h) &rarr; str</code><td>Get name of window
		<tr><td><code>winGetPixel{x,y,wnd} &rarr; int</code><td>Gets the color of the pixel within a window. If wnd is zero the pixel of the whole area is returned. If wnd is not given, the active window is used.
		<tr><td><code>tyleVersion() &rarr; str</code><td>Returns the language version
		<tr><td><code>globals() &rarr; list</code><td>Returns all global variables and built-in functions
		<tr><td><code>spawn(expr) &rarr; int</code><td>creates new thread and executes <code>expr</code> with the caller thread ID in <code>$</code>. The result of spawn is the ID of the new thread.
		<tr><td><code>obj.!putt(thread);</code><td>Puts the obj on the queue of the thread.
		<tr><td><code>gett(timeout) &rarr; obj</code><td>Gets the first object on the queue. If <code>timeout</code> is <code>()</code> it is infinite.
	</table>
  <h1>Type conversion</h1>
  Tyle uses automatic type conversion, with the following convention: In a binary operation, the left operand determines the resulting type. In <code>&&</code> and <code>||</code> both operands are converted to integer. The <code>x(y)</code> expression can be used to convert <code>y</code> to type of <code>x</code>. For regular expressions, the append parameters are taken from <code>x</code>:
  <p><code>0("1")     </code> &rarr; <code>1<br>
  0.0(1)     </code> &rarr; <code>1.0<br>
  0{...}     </code> &rarr; if nonempty then: <code>1</code>, else: <code>0</code><br>
  <code>{}("hey")</code> &rarr; <code>{"h","e","y"}<br>
  {}(?($*2))</code> &rarr; <code>{{"$"},"*",{"2"}}</code> (shows the parse tree of an expression)<br>
  </code>`abc`i ( `def` )  </code> &rarr; <code>`def`i</code></p>
	<h1>Creating batch files containing Tyle code.</h1>
	<p>A batch file containing Tyle looks like this:</p>
	<p><tt>
		...Batch commands...<br>
		call tylerun.bat "%~0" [other parameters]<br>
		... other batch commands.<br>
		goto :EOF<br>
		// These slashes indicate the start of Tyle, this text is just a comment.<br>
		...Tyle expressions, where $ contains the list of all parameters, where the first one is the file path...<br>
	</tt></p>
	<p>If the file only contains tyle code, this can be simplified by:</p>
	<p><tt>
		tylerun.bat %0 [other parameters]<br>
		//<br>
		...Tyle expressions...<br></tt>
  </p>
  <h1>Libraries</h1>
	<h2>Base</h2>
  <table>
    <tr><td><code>tylepath</code><td> variable: path of Tyle.
    <tr><td><code>caps(string)</code><td> all upper case
    <tr><td><code>uncaps(string)</code><td> all lower case
    <tr><td><code>nseq{start,length,stride}</code><td> returns sequence of numbers: {start,start+stride, .. start+stride*(length-1)}
    <tr><td><code>ctup(length)</code><td> returns {0,...,length-1}
    <tr><td><code>ctdn(length)</code><td> returns {length-1,...,0}
    <tr><td><code>copy(data)</code><td> returns recursive copy of data
    <tr><td><code>help()</code><td> shows this help file
    <tr><td><code>split{string,splitstring}</code><td>cuts string in list of strings using splitstring as seperator.
    <tr><td><code>linesplit(string)</code><td>cuts string in list of strings using the line boundary.
    <tr><td><code>string.!replace{from,to}</code><td>replaces occurrences of <code>from</code> in <code>string</code> by <code>to</code>. Works on strings and lists.
    <tr><td><code>list2str(list)</code><td>shows the elements as seperate lines 
    <tr><td><code>head(a)</code><td>if it is a list returns the first elements of a, else returns a completely.
    <tr><td><code>pos2str{number,digits}</code><td>returns positive number as a string with zero's prepended.  
    <tr><td><code>diff{a,b}</code><td>returns {{only in a},{only in b},{intersection}}.
		<tr><td><code>&map.!getOrPutm{key,data}</code><td>Gets it from the map, but if it does not exist, first puts the given data in the map (as an initializer).  
	  </table> 
	<h2>System (look at system.tyle file to see the complete list of functions)</h2>
	  <table>
			<tr><td><code>cmd(string)</code><td>converts a shell command to a sys command. Example: <code>sys(cmd('dir /s /b c:\temp'))</code>.
			<tr><td><code>sysf(string)</code><td>like the build-in function <code>sys</code>, except it only returns the output.
			<tr><td><code>exec(string)</code><td>Executes or starts an application.
 			<tr><td><code>dirfiles('c:\temp')</code><td> shows all files in the directory.
 			<tr><td><code>dirdirs('c:\temp')</code><td> shows all subdirectories in the directory.
 			<tr><td><code>getenv(var)</code><td> gets environment variable.
 			<tr><td><code>text.!setenv(var)</code><td> Sets environment variable.			
 		</table>
	<h2>Windows (look at windows.tyle file to see the complete list of functions)</h2>
	  <table>
			<tr><td><code>winKeys('[shi]+hello [shi]{world[shi]}[ret]');</code><td>
			Use <code>"x+y"</code> to hold x while pressing y.<br><code>"x{yzx}"</code> will hold x while pressing y and z.<br>
			The following keys between <code>[...]</code> are defined:<br>
			<code>LBN,RBN,CANCEL,MBN,BACK,TAB,CLEAR,RET,ENTER,KANA,SHI,CTRL,ALT,PAUSE,<br>
			CAP,ESC,SPACE,PRIOR,NEXT,END,HOME,LEFT,UP,RIGHT,DOWN,SEL,PRINT,EXEC,<br>
			SNAP,INS,DEL,HELP,LWIN,RWIN,APPS,NUM0,NUM1,NUM2,NUM3,NUM4,NUM5,NUM6,<br>
			NUM7,NUM8,NUM9,MUL,ADD,SEP,SUB,DEC,DIV,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,<br>
			F11,F12,F13,F14,F15,F16,F17,F18,F19,F20,F21,F22,F23,F24,NUML,SCROLL,<br>
			LSHI,RSHI,LCTRL,RCTRL,LALT,RALT,PROCKEY,ATTN,CRSEL,EXSEL,EREOF,PLAY,<br>
			ZOOM,NONAME,PA1,OEM_CLEAR</code>
			
	  	<tr><td><code>winKeyDelay(millisecs);</code> <td>Changes the key delay used by "winKeys".
	  	<tr><td><code>winSelect{'Notepad','notepad'};</code> <td>Will open the window containing the word <code>Notepad</code> in the title or else execute second argument and try again.
 			<tr><td><code>winClick{x,y}</code><td>Press left mouse button on location (x,y).
 			<tr><td><code>winRightClick{x,y}</code><td>Press right mouse button on location (x,y).
 			<tr><td><code>winMs{eventstring,x,y}</code><td>Generates mouse-events.<br> Use any event from this list:<br>
 			MOVE,LDOWN,LUP,MDOWN,MUP,RDOWN,RUP,WHEEL,MOTION,ABS,NORM<br>
 			Put the names in a string where the events are seperated by comma's.
 		</table>
	<h2>Math (look at math.tyle file to see the complete list of functions)</h2>
	  <table>
			<tr><td><code>sqrt(f)</code><td>Rough estimate of the square root.
 			<tr><td><code>sum(list)</code><td>Calculates the sum of the values in the list.
 			<tr><td><code>mul(list)</code><td>Calculates the multiplication of the values in the list.
 			<tr><td><code>max(list)</code><td>Calculates the maximum of the values in the list.
 			<tr><td><code>min(list)</code><td>Calculates the minimum of the values in the list.
 			<tr><td><code>hex(val)</code><td>Shows a string with the value in hexadecimal notation.
 			<tr><td><code>bin(val)</code><td>Shows a string with the value in binary notation.
 		</table>
	<h2>Regular expressions</h2>
	  <table>
 			<tr><td><code>s.!match(regexp)</code><td>Equivalent to <code>regexp@s</code>, but returns Type <code>[RE_matches]</code>.
 			<tr><td><code>s.!replace{regexp,with}</code><td>Replaces occurrences of the regular expression in <code>s</code> with <code>with</code>.
 			<tr><td><code>s.!onMatch{regexp,func,notfunc}</code><td>Issues a 'match' and applies 'func' on every region found and it applies 'notfunc' on every substring between the regions.
 		</table>
  <h1>Shell expressions</h1>
  #q; &rarr; quit at the end of this parse.<br>
  #T; &rarr; tyle-formatted output; #t &rarr; raw format output<br>
  #C; &rarr; output to clipboard too; #c &rarr; local output only<br>
  <h1>Explanation of files</h1>
  <li>Tyle Shell for windows: tyler.exe
  <li>DLL for windows: tyle.dll<br>
  <li>C header and inline C++-wrapper: tyle.h
  <li>Base functions: base.tyle (which includes some others)
  <li>Example (XML-parse function): xml.tyle
  <hr COLOR="#000000">
  Michiel Visser (c) 2006
  <hr COLOR="#000000">
</body>
</html>
